package FeatureEnrichment;

import java.util.ArrayList;

import Analysis.PengMIClass;
import Utility.WorkerUtilityClass;

public class FastCorrelationBasedFilterSharp 
{
	public ArrayList<Integer> FCBFSharp(double[][] featuresVector, double[] classLabelsVector, int numberToBeSelectedFeature) throws Exception
	{
		//compute feature relevances, i.e. SU between class feature and class labels
		int numberOfFeature = featuresVector.length;
		double[] relevances = new double[numberOfFeature]; 
		
		for (int i=0; i<numberOfFeature; i++)
		{	//MAKE SURE THAT NORMALIZATION IS DONE BIN=3
			relevances[i]=PengMIClass.getMutualInfo(featuresVector[i], classLabelsVector);
		}
		//Order feature indices according to their relevance values.
		ArrayList<Integer> relevancesDecreasingOrderFeatureIndex = SortIncreasing(relevances);
		ArrayList<Integer> relevancesIncreasingOrderFeatureIndex = SortDecreasing(relevances);
		ArrayList<Integer> previousIndexes = new ArrayList<Integer> ();
		ArrayList<Integer> currentIndexes = new ArrayList<Integer> ();
		
		for(int i=0; i<relevances.length;i++)
		{
			previousIndexes.add(i);
			currentIndexes.add(i);
		}
		
		for(int selectedFeature=0, indexP=0; selectedFeature<numberToBeSelectedFeature ;)
		{
			//index of the temporarily predominant feature
			int index = 0;
			while (0 < relevancesIncreasingOrderFeatureIndex.size())
			{
				//get head
				
				int predominantFeature = relevancesIncreasingOrderFeatureIndex.get(indexP);
				
				int numEliminated = 0;
			
				while (0 < relevancesDecreasingOrderFeatureIndex.size() && numEliminated < 1 )
				{
					//get head
					int q = relevancesDecreasingOrderFeatureIndex.get(0);
					//feature p could eliminate only a less relevant feature.
					if(predominantFeature == q)
					{
						break;
					}
					
					if (PengMIClass.getMutualInfo(featuresVector[predominantFeature], featuresVector[q]) >= relevances[q])
					{

						previousIndexes = currentIndexes;
						currentIndexes.remove(q);
						relevancesDecreasingOrderFeatureIndex.remove(q);
						relevancesDecreasingOrderFeatureIndex.remove(q);
						numEliminated = 1;
					}
					else
					{
						index++;
						q = relevancesDecreasingOrderFeatureIndex.get(index);
					}
				}
				indexP++;
				predominantFeature = relevancesIncreasingOrderFeatureIndex.get(indexP);
			}
			
			if(currentIndexes.size() == previousIndexes.size())
			{
				break;
			}
		}
		
		return currentIndexes;
		
	}
	
	
	public ArrayList<Integer> SortIncreasing(double[] relevances)
	{
		ArrayList<Integer> sortingOrder =new ArrayList<Integer>();
		
		for(int i=0; i<relevances.length ;i++)
		{
			int maxIndex= WorkerUtilityClass.findMaxIndexForTheGivenVector(relevances);
			sortingOrder.add(maxIndex);
			relevances[maxIndex] = -1000;
		}
		
		return sortingOrder;
		
	}
	
	public ArrayList<Integer> SortDecreasing(double[] relevances)
	{
		ArrayList<Integer> increasingOrder = SortIncreasing(relevances);
		
		for(int head=0, tail=increasingOrder.size()-1; head<tail; head++,tail--)
		{
			int temp=increasingOrder.get(head);
			increasingOrder.set(head, increasingOrder.get(tail));
			increasingOrder.set(tail, temp);
		}
		
		return increasingOrder;
	}
}
